/* Copyright (c) 2015,2016 Lucky Byte, Inc.
 */
package com.lucky_byte.pay.jar.lualib;

import java.io.File;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import com.lucky_byte.pay.jar.LuaInterp;
import com.lucky_byte.pay.jar.Runtime;
import com.lucky_byte.pay.jar.Version;
import com.lucky_byte.pay.jar.WebNotify;

public class LuaRuntime extends TwoArgFunction
{
	private static final Logger logger = LogManager.getLogger();

	private final LuaInterp interp;

	public LuaRuntime(LuaInterp interp) {
		this.interp = interp;
	}

	@Override
	public LuaValue call(LuaValue modname, LuaValue env) {
		env.set("product", LuaValue.valueOf(Version.APPNAME));
		env.set("vendor", LuaValue.valueOf(Version.VENDOR));
		env.set("version", LuaValue.valueOf(Version.VERSION));
		env.set("copyright", LuaValue.valueOf(Version.COPYRIGHT));

		env.set("secl", LuaValue.valueOf(Runtime.secureLevel()));
		env.set("eval", new Eval());

		LuaValue runtime = tableOf();
		env.set("runtime", runtime);

		runtime.set("load_plugins", new LoadPlugins());
		runtime.set("basedir", Runtime.basePath());
		runtime.set("path_for", new PathFor());

		LuaValue notify = tableOf();
		env.set("notify", notify);
		notify.set("notify", new Notify());

		return runtime;
	}

	/**
	 * 执行 Lua 脚本文件
	 */
	class Eval extends OneArgFunction
	{
		@Override
		public LuaValue call(LuaValue arg) {
			String path = arg.checkjstring();
			if (!path.startsWith("/")) {
				path = Runtime.pathFor("/scripts/" + path);
			}
			File file = new File(path);
			if (!file.exists()) {
				logger.error("脚本文件[{}]不存在.", path);
				return LuaValue.NIL;
			}
			return interp.eval(file);
		}
	}

	/**
	 * 加载 Lua 插件
	 */
	class LoadPlugins extends OneArgFunction
	{
		@Override
		public LuaValue call(LuaValue arg) {
			String path = arg.checkjstring();
			return LuaValue.valueOf(interp.loadPlugins(new File(path)));
		}
	}


	/**
	 * 基于工作目录查找一个文件的全路径
	 */
	class PathFor extends OneArgFunction
	{
		@Override
		public LuaValue call(LuaValue arg) {
			String path = Runtime.pathFor(arg.checkjstring());
			if (path == null) {
				return LuaValue.NIL;
			}
			return LuaValue.valueOf(path);
		}
	}

	/**
	 * 发送站内通知
	 */
	class Notify extends VarArgFunction
	{
		@Override
		public Varargs invoke(Varargs args) {
			int level = args.checkint(1);
			String message = args.checkjstring(2);
			switch (level) {
			case 1:
				logger.info(message);
				break;
			case 2:
				logger.warn(message);
				break;
			case 3:
				logger.error(message);
				break;
			case 4:
			default:
				logger.fatal(message);
				break;
			}
			return LuaValue.valueOf(WebNotify.notify(level, message));
		}
	}
}
